using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using KLATencor.CommonApp.Infrastructure.StateMachine;
using StateMachine_Graphical_Editor.Shapes;

namespace StateMachine_Graphical_Editor.Forms
{
    /// <summary>
    /// Displays properties of a selected state
    /// </summary>
    public partial class StateProperties : Form
    {
        #region members:

        /// <summary>
        /// The selected graphical stae this form represent
        /// </summary>
        private GState selectedState;

        /// <summary>
        /// State machine
        /// </summary>
        private StateMachine m_Machine = null;

        /// <summary>
        /// Parent State of the current state
        /// </summary>
        private State pState;

        /// <summary>
        /// Collection of sub states of the state represented by this form
        /// </summary>
        private StateCollection stateCollection;

        private bool dirty = false; //for asking if to save or not
        
        /// <summary>
        /// Indcate if in edit mode or create mode
        /// </summary>
        private bool editMode = false; // for editing Mode

        #region Constants:

        private const string TITLE = " - Properties";
        private const String ROOT_PARENT = "Machine";

        #endregion

        #endregion

        #region C'tors:

        public StateProperties()
        {
            InitializeComponent();
        }

        public StateProperties(GState selected, StateMachine machine, State parentState) 
            : this()
        {
            stateCollection = parentState != null ? parentState.Substates : machine.States;
            // save a reference to the state
            this.selectedState = selected;
            this.m_Machine = machine;
            this.pState = parentState;
            this.Text = selected.Name + TITLE;
            
            layoutParameters(); //display all parameters form the state
        }

        #endregion

        #region Event handlers:

        private void cancelButton_Click(object sender, EventArgs e)
        {
            //if new state, remove it from diagram
            if(!editMode) 
                selectedState.Form.Diagram.Model.RemoveChild(selectedState);

            Close();
        }

        private void okButton_Click(object sender, EventArgs e)
        {
            if (!validateInput())
                return;

            // TODO: save properties to the state Object
            // AND to file!!
            selectedState.Name = this.stateNameTextBox.Text;
            selectedState.Labels[0].Text = selectedState.Name;
            selectedState.ID = Convert.ToInt32( this.stateIdTextBox.Text);
            selectedState.StateType = stateTypeBox.SelectedItem.ToString();
            selectedState.AbbrevName = this.abbrevNameTextBox.Text;
            selectedState.CustomStateFile = this.customStateFileTextBox.Text;
            selectedState.CustomStateClass = this.customStateClassTextBox.Text;
            selectedState.UseHistory = this.yesRadioButton.Checked;
            selectedState.Action = 
                actionComboBox.SelectedItem != null ? 
                actionComboBox.SelectedItem.ToString() :
                null;

            selectedState.IsInitialState = initialStateCheckBox.Checked;
            State s = m_Machine.AllStates.Find(this.stateNameTextBox.Text);
            // edit Mode is set to true if editing is in afact
            if (editMode) 
            {
                if (dirty) //dirty not in use yet
                {
                    // TODO : to remove the state from the collection, change the wanted 
                    //        parameters and and put the new, modified state back.
                    long stateId = Int64.Parse(stateIdTextBox.Text);
                    State newState = new State(
                        m_Machine, stateNameTextBox.Text, stateId,
                        abbrevNameTextBox.Text, initialSubStateTextBox.Text,
                        yesRadioButton.Checked, pState);
                }
            }
            else
            {
                long stateId = Int64.Parse(this.stateIdTextBox.Text);
                State logicState = 
                    new State(
                        m_Machine, 
                        stateNameTextBox.Text, 
                        stateId,
                        abbrevNameTextBox.Text, 
                        initialSubStateTextBox.Text, 
                        yesRadioButton.Checked, 
                        pState);
                
                stateCollection.AddState(logicState);

                //assign the logic state to the GState
                selectedState.LogicState = logicState;
            }
            
            this.Close();
        }

        #endregion

        #region private Methods:

        //TODO: displays the form as grayed out when machine is runing:
        //is necessary? - maybe not show the form at all?
        public void disableForm()
        {
            foreach (Control control in this.Controls)
            {
                control.Enabled = false;
            }
        }

        /// <summary>
        /// Indicate that form is in edit mode (an existing state)
        /// </summary>
        public void EditWanted()
        {
            this.editMode = true;
            this.dirty = false;
        }

        /// <summary>
        /// Make sure that all mandatory fields are fed with data
        /// </summary>
        /// <returns>true for valid form, false if not</returns>
        private bool validateInput()
        {
            //reset labels
            stateNameLabel.ForeColor = Color.Black;
            stateIdLabel.ForeColor = Color.Black;

            bool stateNameOK = stateNameTextBox.Text != null && !stateNameTextBox.Text.Equals("");
            bool stateIdOK = stateIdTextBox.Text != null && !stateIdTextBox.Text.Equals("");

            if (stateNameOK && stateIdOK)
                return true;

            else
            {
                MessageBox.Show(
                "You must feed a valid name and Id",
                "Validation error:",
                MessageBoxButtons.OK,
                MessageBoxIcon.Error);

                stateNameLabel.ForeColor = stateNameOK ? Color.Black : Color.Red;
                stateIdLabel.ForeColor = stateIdOK ? Color.Black : Color.Red;

                return false;
            } 
        }

        /// <summary>
        /// Set the parameters known from the selected GState
        /// </summary>
        private void layoutParameters()
        {
            //State name
            this.stateNameTextBox.Text = selectedState.Name;
            //StateID
            displayStateId();
            //AbbrevName
            this.abbrevNameTextBox.Text = selectedState.AbbrevName;
            this.customStateClassTextBox.Text = selectedState.CustomStateClass;
            this.customStateFileTextBox.Text = selectedState.CustomStateFile;
            this.actionComboBox.Text = selectedState.Action;
            //Action
            displaySelectedType(actionComboBox, selectedState.Action);
            //Parent
            parentTextBox.Enabled = false;

            if (pState != null)
                parentTextBox.Text = pState.Name;
            else
                parentTextBox.Text = ROOT_PARENT;
            //State Type
            displaySelectedType(stateTypeBox, selectedState.StateType);
            
            //is Initial?
            if (selectedState.IsInitialState)
            {
                initialStateCheckBox.Checked = true;
                //allow only to check the box not uncheck
                initialStateCheckBox.Enabled = false;
            }
            //Initial subState
            if (selectedState.hasSubStates())
            {
                initialSubStateTextBox.Visible = true;
                initialSubStateLabel.Visible = true;
                initialSubStateTextBox.Text = selectedState.InitialSubStateName;
            }
            //else
            //    initialSubStateTextBox.Enabled = false;
            
            //Use history?
            displayStateUseHistory();
        }

        private void displayStateId()
        {
            //check if GState is new or from machine:
            if (selectedState.ID == -1) //new state created by user
            {
                //this.stateIdTextBox.Enabled = true;
                this.stateIdTextBox.Text = "";
            }
            else
            {
                this.stateIdTextBox.Text = selectedState.ID.ToString();
            }
        }

        /// <summary>
        /// Select an item do display in a combo box 
        /// </summary>
        /// <param name="box">The combo box to handle</param>
        /// <param name="toSelect">The item to select</param>
        private void displaySelectedType(ComboBox box, String toSelect)
        {
            if (String.IsNullOrEmpty(toSelect))
                return;

            int index = box.Items.IndexOf(toSelect);
            stateTypeBox.SelectedItem = 
                index > -1 ? 
                stateTypeBox.Items[index]:
                stateTypeBox.Items[0];
        }

        /// <summary>
        /// Select radion button to check
        /// </summary>
        private void displayStateUseHistory()
        {
            if (selectedState.UseHistory)
                yesRadioButton.Checked = true;
            else
                noRadioButton.Checked = true;
        }

        #endregion
    }
}